Option Explicit On
Option Strict On

Imports TreeCreeper01Interfaces

Friend Class cAbstractDataAgent
    Implements IDisposable

    Protected pOverrideReader As cTaxonomicOverrideReader
    Protected pSourceFileType As eSourceFileType

    Friend TaxonomicDataColumnScanStartIndex As Integer
    Friend TaxonomicDataColumnScanEndIndex As Integer
    Friend AbstractReader As cAbstractReader




    Sub New(ByVal TaxonomicOverrideFilename As String)
        If Not TaxonomicOverrideFilename = "" Then
            pOverrideReader = New cTaxonomicOverrideReader(TaxonomicOverrideFilename)
        End If
    End Sub

    Sub Destroy() Implements IDisposable.Dispose
        Me.AbstractReader = Nothing
    End Sub

    Friend Sub PopulateTaxonomicTree(ByVal TaxonomicTree As ITaxonomicTree)

        Dim CurrentNode As ITaxonomicTreeNode
        Dim RowIterator As Integer
        Dim ColumnIterator As Integer
        Dim Name As String
        Dim NewUniqueKey As String

        For RowIterator = IndexOfFirstDataRow To AbstractReader.NumberOfRows

            'Get root node
            CurrentNode = TaxonomicTree.RootNode

            For ColumnIterator = TaxonomicDataColumnScanEndIndex To TaxonomicDataColumnScanStartIndex Step -1

                Name = AbstractReader.GetStringValue(RowIterator, ColumnIterator)

                If ColumnIterator = TaxonomicDataColumnScanStartIndex Then
                    NewUniqueKey = GenerateUniqueKeyForSpecies(RowIterator)
                Else
                    NewUniqueKey = Name
                End If

                CurrentNode = CreateChildNodeIfNotExistAndTravelToIt(CurrentNode, NewUniqueKey, Name)
            Next

        Next

        If Not pOverrideReader Is Nothing Then
            Call pOverrideReader.WriteToLookup(TaxonomicTree.CreateOverrideDistanceLookupTable)
        End If

    End Sub

    Friend Sub PopulateSpeciesAbundances(ByVal Abundances As IAbundanceCollection, ByVal TaxonomicSpeciesCollection As ITaxonomicSpeciesCollection)

        Dim ColumnIndex As Integer
        Dim RowIndex As Integer
        Dim Index As Integer
        Dim Abundance As Double
        Dim SpeciesUniqueKey As String
        Dim TaxonomicSpeces As ITaxonomicSpecies
        Dim UniqueKey As String

        If AbstractReader.DoesHaveNumericFirstColumn Then
            ColumnIndex = 1
            For RowIndex = IndexOfFirstDataRow To AbstractReader.NumberOfRows
                Abundance = CType(AbstractReader.ReadDoubleValue(RowIndex, ColumnIndex), Double)
                SpeciesUniqueKey = GenerateUniqueKeyForSpecies(RowIndex)
                Abundances.AddAbundance(SpeciesUniqueKey, Abundance)
            Next
        Else
            With TaxonomicSpeciesCollection
                For Index = 1 To .Count
                    TaxonomicSpeces = .TaxonomicSpeciesByIndexBaseOne(Index)
                    UniqueKey = TaxonomicSpeces.UniqueKey()
                    Abundances.AddAbundance(UniqueKey, 1)
                Next
            End With
        End If

    End Sub

    Friend Function GenerateUniqueKeyForSpecies(ByVal RowIndex As Integer) As String

        Dim NewUniqueKey As String
        Dim ColumnIterator As Integer

        NewUniqueKey = ""

        For ColumnIterator = TaxonomicDataColumnScanStartIndex To TaxonomicDataColumnScanEndIndex
            NewUniqueKey &= AbstractReader.GetStringValue(RowIndex, ColumnIterator) & "-"
        Next

        NewUniqueKey = Left(NewUniqueKey, Len(NewUniqueKey) - 1)
        Return NewUniqueKey

    End Function

    Private Function CreateChildNodeIfNotExistAndTravelToIt(ByVal CurrentNode As ITaxonomicTreeNode, ByVal UniqueKey As String, ByVal NodeName As String) As ITaxonomicTreeNode

        'check if the leaf exists
        If Not CurrentNode.DoesChildExist(UniqueKey) Then
            CurrentNode = CurrentNode.AddChildNode(UniqueKey, NodeName)
        Else
            CurrentNode = CurrentNode.ChildNodeItemByKey(UniqueKey)
        End If

        Return CurrentNode

    End Function

End Class
